<script lang="tsx">
  import type { PropType } from "vue";
  import { Result, Button } from "ant-design-vue";
  import { defineComponent, ref, computed, unref } from "vue";
  import { ExceptionEnum } from "/@/enums/ExceptionEnum";
  import notDataSvg from "/@/assets/svg/no-data.svg";
  import netWorkSvg from "/@/assets/svg/net-error.svg";
  import { useRoute } from "vue-router";
  import { useDesign } from "/@/hooks/web/UseDesign";
  import { useI18n } from "/@/hooks/web/UseI18n";
  import { useGo, useRedo } from "/@/hooks/web/UsePage";
  import { usePermissionStore } from "/@/store/modules/Permission";
  import { PageEnum } from "/@/enums/PageEnum";

  interface MapValue {
    title: string;
    subTitle: string;
    btnText?: string;
    icon?: string;
    handler?: Fn;
    status?: string;
  }

  export default defineComponent({
    name: "ErrorPage",
    props: {
      // 状态码
      status: {
        type: Number as PropType<number>,
        default: ExceptionEnum.PAGE_NOT_FOUND
      },

      title: {
        type: String as PropType<string>,
        default: ""
      },

      subTitle: {
        type: String as PropType<string>,
        default: ""
      },

      full: {
        type: Boolean as PropType<boolean>,
        default: false
      }
    },
    setup(props) {
      const statusMapRef = ref(new Map<string | number, MapValue>());
      const { query } = useRoute();
      const go = useGo();
      const redo = useRedo();
      const { t } = useI18n();
      const { prefixCls } = useDesign("app-exception-page");
      const getStatus = computed(() => {
        const { status: routeStatus } = query;
        const { status } = props;
        return Number(routeStatus) || status;
      });
      const getMapValue = computed((): MapValue => {
        return unref(statusMapRef).get(unref(getStatus)) as MapValue;
      });
      const backLoginI18n = t("sys.exception.backLogin");
      const backHomeI18n = t("sys.exception.backHome");
      const permissionStore = usePermissionStore();
      unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
        title: "403",
        status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
        subTitle: t("sys.exception.subTitle403"),
        btnText: props.full ? backLoginI18n : backHomeI18n,
        handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go(permissionStore.homePath))
      });

      unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
        title: "404",
        status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
        subTitle: t("sys.exception.subTitle404"),
        btnText: props.full ? backLoginI18n : backHomeI18n,
        handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go(permissionStore.homePath))
      });

      unref(statusMapRef).set(ExceptionEnum.ERROR, {
        title: "500",
        status: `${ExceptionEnum.ERROR}`,
        subTitle: t("sys.exception.subTitle500"),
        btnText: backHomeI18n,
        handler: () => go()
      });

      unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
        title: t("sys.exception.noDataTitle"),
        subTitle: "",
        btnText: t("common.redo"),
        handler: () => redo(),
        icon: notDataSvg
      });

      unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
        title: t("sys.exception.networkErrorTitle"),
        subTitle: t("sys.exception.networkErrorSubTitle"),
        btnText: t("common.redo"),
        handler: () => redo(),
        icon: netWorkSvg
      });

      return () => {
        const { title, subTitle, btnText, icon, handler, status } = unref(getMapValue) || {};
        return (
          <Result
            class={prefixCls}
            status={status as any}
            title={props.title || title}
            sub-title={props.subTitle || subTitle}
          >
            {{
              extra: () =>
                btnText && (
                  <Button type='primary' onClick={handler}>
                    {() => btnText}
                  </Button>
                ),
              icon: () => (icon ? <img src={icon} /> : null)
            }}
          </Result>
        );
      };
    }
  });
</script>
<style lang="less">
  @prefix-cls: ~"@{namespace}-app-exception-page";

  .@{prefix-cls} {
    display: flex;
    align-items: center;
    flex-direction: column;

    .ant-result-icon {
      img {
        max-width: 400px;
        max-height: 300px;
      }
    }
  }
</style>
